package com.example.androidstudy.ui.demo.paging3

import android.content.Context
import androidx.paging.*
import androidx.room.withTransaction
import com.example.androidstudy.extend.logE
import com.example.androidstudy.ui.demo.recyclerview.NumberInfo
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityRetainedComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ActivityRetainedScoped
import java.lang.Exception

@Module
@InstallIn(ActivityRetainedComponent::class)
 class Paging3DemoDI {
    @ActivityRetainedScoped
    @Provides
    fun providerDb(@ApplicationContext context: Context):NumberInfoDb = NumberInfoDb.create(context, true)

    @ExperimentalPagingApi
    @Provides
    fun providerPagingDataSource(db: NumberInfoDb) =
        if (false) Pager(config = PagingConfig(pageSize = 20), initialKey = 0) {
            object : PagingSource<Int, NumberInfo>() {
                override fun getRefreshKey(state: PagingState<Int, NumberInfo>): Int? {
                    "refresh:$state".logE()
                    return state.pages.last().nextKey
                }

                override suspend fun load(params: LoadParams<Int>): LoadResult<Int, NumberInfo> {
                    "$params:${params.key}".logE()
                    if (params.key == null) return LoadResult.Error(Exception("mock"))
                    val data = mutableListOf<NumberInfo>().apply {
                        (1..10).forEach {
                            add(NumberInfo(it + params.key!!))
                        }
                    }
                    return LoadResult.Page(data, null, data.size + params.key!!)
                }

            }
        } else Pager(
            config = PagingConfig(pageSize = 10),
            initialKey = 0,
            remoteMediator = object : RemoteMediator<Int, NumberInfo>() {
                override suspend fun load(
                    loadType: LoadType,
                    state: PagingState<Int, NumberInfo>
                ): MediatorResult {
                    val dao = db.dao()

                    var key = when (loadType) {
                        LoadType.REFRESH -> null
                        LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
                        LoadType.APPEND -> {
                            val count = db.withTransaction {
                                dao.count()
                            }
                            if (count > 100) {
                                return MediatorResult.Success(endOfPaginationReached = true)
                            }

                            count
                        }
                    }

                    if (key == null) {
                        db.withTransaction {
                            dao.deleteAll()
                        }
                        key = 0
                    }
                    "key:$key".logE()
                    val data = mutableListOf<NumberInfo>().apply {
                        (1..10).forEach {
                            add(NumberInfo(it + key!!))
                        }
                    }
                    db.withTransaction {
                        dao.insertAll(data)
                    }
                    return MediatorResult.Success(endOfPaginationReached = false)
                }
            }) {
            db.dao().all()
        }

}

